/*
 * Implementation of ShadowPage
 *
 * Author: Zhang Yichao
 * Origin from: Mickey Leen
 * Date: 2010-4-20
 *
 * 		G-Crossbit Group
 */

#include "crossbit/ShadowPage.h"
#include <iostream>

using namespace crossbit;

ShadowPage::ShadowPage()
{
	page_table = new PageData*[PAGE_NUM];
	for( int i = 0; i < PAGE_NUM; i++ )
	{
		page_table[i] = NULL;
	}
}

void ShadowPage::readMem( XTMemAddr addr, XTInt32 size )
{
	if( (addr&0x3fff0000 != 0x3fff0000) && addr > SYSCALL::sys_brk )
	{
		printf("Access error! Over Sys_Brk! addr: %x, sys_brk: %x\n", addr, SYSCALL::sys_brk);
	}
}

void ShadowPage::writeMem( XTMemAddr addr, XTInt32 size, XTUint32 value )
{
	PageData *&page = page_table[ PAGE_INDEX(addr) ];
	if( NULL == page )
	{
		page = new PageData;
		UTIL::XTMemcpy( (void*)page->mem_data, (void*)PAGE_ALIGN(addr), PAGE_SIZE);
	}

	switch( size )
	{
		case WORD:
			*(XTUint32*)(page->mem_data+PAGE_OFFSET(addr)) = value;
			*(XTUint32*)addr = value;
			break;
		case HALFWORD:
			*(XTUint16*)(page->mem_data+PAGE_OFFSET(addr)) = value;
			*(XTUint16*)addr = value;
			break;
		case BYTE:
			*(XTUint8*)(page->mem_data+PAGE_OFFSET(addr)) = value;
			*(XTUint8*)addr = value;
			break;
	}
}

void ShadowPage::dumpMemData( XTFile fd )
{
	PageData *page;
	for( int i = 0; i < PAGE_NUM; i++ )
	{
		page = page_table[i];
		if ( page != NULL )
		{
			SYSCALL::XTWrite(fd, &i, sizeof(XTUint32));	
			SYSCALL::XTWrite(fd, page->mem_data, PAGE_SIZE);	
		}
	}	
}

void ShadowPage::loadMemData( XTFile fd )
{
	PageData *page;
	int index;

	int ret = SYSCALL::XTRead(fd, &index, sizeof(XTUint32));	
	while( ret && ret != -1 )
	{
		PageData *&page = page_table[index];	
		if( NULL == page )
			page = new PageData;
		SYSCALL::XTRead(fd, page->mem_data, PAGE_SIZE);	
		XTMemAddr addr = index<<12;
		UTIL::XTMemcpy( (void*)PAGE_ALIGN(addr), (void*)page->mem_data, PAGE_SIZE);
		//std::cout<<std::hex<<"0x"<<addr<<std::endl;

		ret = SYSCALL::XTRead(fd, &index, sizeof(XTUint32));	
	}
}
